# write by hashaki
# first edit on 2018/12/20
# last change on 2019/03/26
# 用于测试交易引擎tradeEngine.py
import numpy as nd
import pandas as pd
import talib
import math
from datetime import datetime

class HaStrategyTest:
    def __init__(self):
        self.orderDict={}                     # 用于保存下单数据的字典
        self.cancelList=[]                    # 撤单列表
        self.side=0                           # 方向
        self.resultDict={}                    # 下单结果
        self.cash=0                      # 现金
        self.pos=0                            # 持仓
        self.capital=0                   # 总资产

    # ----------------------------------------------------------------------------------
    # 需要用户去编写的函数
    def next(self,data):
        '''策略模块的入口，接收引擎推送过来的数据，被动触发执行策略文件，data可以为tick,bar,depth没有限定'''
        bids_price=[]
        asks_price=[]
        bids_volume=[]
        asks_volume=[]
        for i,k in zip(data['bids'],data['asks']):
            bids_price.append(float(i[0]))
            asks_price.append(float(k[0]))
            bids_volume.append(float(i[1]))
            asks_volume.append(float(k[1]))
        
        sum_asks=round(sum(asks_volume),4)
        sum_bids=round(sum(bids_volume),4)

        if sum_asks/sum_bids > 1.5:
            if self.pos==0:
                return

            if self.side==-1:
                return
            else:
                self.sell(data['target_symbol'],bids_price[0],bids_volume[0])
                print('下单：',data['target_symbol'],' ',bids_price[0],' ',bids_volume[0])

                self.side-=1

                self.capital=self.cash+self.pos*bids_price[0]
        
        elif sum_asks/sum_bids<0.5:
            if self.cash==0:
                return

            if self.side==1:
                return

            else: 
                self.buy(data['target_symbol'],asks_price[-1],asks_volume[-1])
                print('下单：',data['target_symbol'],' ',asks_price[-1],' ',asks_volume[-1])
                    
                self.side+=1
        
                self.capital=self.cash+self.pos*asks_price[-1]
    
    def onOrder(self):
        '''当下单行为触发时被动执行的函数'''
        time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print('时间 ：{}   总资产：{} 初始资金：3000  持有现金：{}   持仓：{}'.format(time,self.capital,self.cash,self.pos))
    
    def onTrade(self):
        '''当成交时触发的被动执行函数'''
        pass
    
    # ----------------------------------------------------------------------------------
    # 辅助编写策略的模块
    def buy(self,target_symbol,price,volume):
        '''下单买功能'''
        self.onOrder()
        self.orderDict.clear()
        self.orderDict['side']='buy'
        self.orderDict['target_symbol']=target_symbol
        self.orderDict['price']=price
        self.orderDict['volume']=volume
    
    def sell(self,target_symbol,price,volume):
        '''下单卖功能'''
        self.onOrder()
        self.orderDict.clear()
        self.orderDict['side']='sell'
        self.orderDict['target_symbol']=target_symbol
        self.orderDict['price']=price
        self.orderDict['volume']=volume
    
    def cancelOrder(self,orderID=None):
        '''撤单，当orderID为空的时候，全部撤单'''
        self.onOrder()
        if orderID:
            self.cancelList.append(orderID)
        else:
            # TODO : 全部撤单实现
            pass
    
    def returnOrder(self):
        '''返回一个下单字典给引擎,策略模块的出口'''
        return self.orderDict
    
    def getHistory(self):
        '''获取当前时间的前N个历史数据'''
        pass
    
    # ------------------------------------------------------------------
    # 我自己的特色功能函数
    def getHourPriceChange(self):
        '''计算一个小时内，成交曲线的开始值与结束值的连线的斜率'''
        pass

    def calculateSidePower(self):
        '''调用这个函数，next推送的必须是深度数据，比较买卖双方的能量'''
        pass
    
    def checkSideEat(self):
        '''调用这个函数，next推送的必须是深度数据，有时候买卖双方的挂单量并不能代表能量，因为有很多用户是发停止单的'''
        pass
    
    def getAccountCash(self):
        '''获取账户现金'''
        pass
    
    def getAccountPos(self):
        '''获取账户持仓'''
        pass
    